<?php
// +----------------------------------------------------------------------
// | 海豚PHP框架 [ DolphinPHP ]
// +----------------------------------------------------------------------
// | 版权所有 2016~2017 河源市卓锐科技有限公司 [ http://www.zrthink.com ]
// +----------------------------------------------------------------------
// | 官方网站: http://dolphinphp.com
// +----------------------------------------------------------------------
// | 开源协议 ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------

namespace plugins\AliSms\controller;

use app\common\controller\Common;
use plugins\AliSms\model\AliSms as SmsModel;

// 阿里云 SDK 类（如果需要可以取消注释）
// use Aliyun\Core\Profile\DefaultProfile;
// use Aliyun\Core\DefaultAcsClient;
// use Aliyun\Api\Sms\Request\V20170525\SendSmsRequest;

/** 
 * sms控制器
 * @package plugins\Sms\controller
 */
class AliSms extends Common
{
    /**
     * 发送短信
     * @param string $rec_num 短信接收号码
     * @param array $sms_param 短信模板变量
     * @param string $sms_template 短信模板名称
     * @param string $sms_extend
     *      公共回传参数，在“消息返回”中会透传回该参数；举例：用户可以传入自己下级的会员ID，
     *      在消息返回时，该会员ID会包含在内，用户可以根据该会员ID识别是哪位会员使用了你的应用
     * @author MrGuo <gj2517@qq.com>
     * @return array 
     *
     * $result = plugin_action('Sms/Sms/send', ['手机号码', [模板变量], '模板名称']);
     * if($result['code']){
     *     $this->error('发送失败，错误代码：'. $result['code']. ' 错误信息：'. $result['msg']);
     * } else {
     *     $this->success('发送成功');
     * }
     */
    public function send($mobile = '', $action = "", array $param = [])
    {
        $config = plugin_config('alisms');

        if (empty($config['akid'])) {
            return array('code' => 2, 'msg' => '请填写APPKEY');
        }
        if (empty($config['aksecret'])) {
            return array('code' => 3, 'msg' => '请填写SECRET');
        }
        if (empty($mobile)) {
            return array('code' => 4, 'msg' => '请填写短信接收号码');
        }
        if (empty($action)) {
            return array('code' => 5, 'msg' => '内部指令错误');
        }

        $template = SmsModel::getTemplate($action);
        if (!$template) {
            return array('code' => 7, 'msg' => '找不到短信模板或未启用');
        }

        // 模板参数
        if ($template['status'] == '0') {
            return array('code' => 8, 'msg' => '短信模板已禁用');
        }
        if ($template['code'] == '') {
            return array('code' => 9, 'msg' => '请设置模板ID');
        }
        if ($template['sign_name'] == '') {
            return array('code' => 10, 'msg' => '请设置签名名称');
        }

        $ret = $this->sendSms($config, $mobile, $template['sign_name'], $template['code'], $param);

        if (isset($ret->Code) && $ret->Code == "OK") {
            return ['code' => 0, 'data' => ["mobile" => $mobile, 'param' => $param], "msg" => "OK"];
        } else {
            return ['code' => 500, 'data' => ["mobile" => $mobile, 'param' => $param], "msg" => $ret->Message];
        }
    }

    /**
     * 发送短信
     * @param string $mobile 手机号
     * @param string $signName 签名名称
     * @param string $templateCode 模板代码
     * @param array $param 模板参数
     * @return object
     */
    private function sendSms($config, $mobile, $signName, $templateCode, $param = [])
    {
        // 构建请求参数
        $params = [
            'PhoneNumbers' => $mobile,
            'SignName' => $signName,
            'TemplateCode' => $templateCode,
            'TemplateParam' => json_encode($param),
            'RegionId' => 'cn-hangzhou',
            'Action' => 'SendSms',
            'Version' => '2017-05-25',
            'AccessKeyId' => $config['akid'],
            'SignatureMethod' => 'HMAC-SHA1',
            'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'),
            'SignatureVersion' => '1.0',
            'SignatureNonce' => uniqid(),
            'Format' => 'JSON'
        ];

        // 生成签名
        $signature = $this->generateSignature($params, $config['aksecret']);
        $params['Signature'] = $signature;

        // 发送请求
        $url = 'https://dysmsapi.aliyuncs.com/';
        $response = $this->httpPost($url, $params);

        return json_decode($response);
    }

    /**
     * 生成签名
     */
    private function generateSignature($params, $accessKeySecret)
    {
        ksort($params);
        $stringToSign = 'POST&%2F&' . urlencode(http_build_query($params, '', '&', PHP_QUERY_RFC3986));
        return base64_encode(hash_hmac('sha1', $stringToSign, $accessKeySecret . '&', true));
    }

    /**
     * 发送 HTTP POST 请求
     */
    private function httpPost($url, $params)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/x-www-form-urlencoded'
        ]);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode !== 200) {
            return json_encode(['Code' => 'RequestFailed', 'Message' => 'HTTP请求失败']);
        }

        return $response;
    }
}
